package maa.dao.h2;

import maa.dao.DAOException;
import maa.dao.DAOManager;
import maa.dao.ClientDAO;
import maa.dao.DAOCommand;
import maa.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class ClientDAOimpl implements DAOCommand, ClientDAO {
    private static final Logger logger = LoggerFactory.getLogger(MentorDAOimpl.class);
    private static final String REMOVE_SUBSCRIBTION = "DELETE from client_subscription where clientid=? and courseid = ?";
    private final String ADD_SUBSCRIBTION = "INSERT INTO client_subscription(clientid,courseid) values(?,?)";
    private final String FIND_USER_SUBSCRIPTIONS = "Select courseid from client_subscription where clientid = ?";
    private Connection connection;

    public ClientDAOimpl() {
    }

    public ClientDAOimpl(Connection connection) {
        this.connection = connection;

    }

    public List<UUID> findUserSubscriptions(User user) throws DAOException {
        List<UUID> list = new ArrayList<>();
        if (connection != null) {
            PreparedStatement preparedStatement = null;
            try {
                preparedStatement = connection.prepareStatement(FIND_USER_SUBSCRIPTIONS);
                preparedStatement.setObject(1, user.getUuid());
                ResultSet set = preparedStatement.executeQuery();
                while (set.next()) {
                    list.add((UUID) set.getObject("courseid"));
                }
            } catch (SQLException e) {
                logger.error("Could not find user subscriptions " + e.getMessage());
                throw new DAOException(e.getMessage());
            } finally {
                if (preparedStatement != null) {
                    close(preparedStatement);
                }
            }
        } else {
            throw new DAOException("No connection available");
        }
        return list;
    }

    public boolean addCourse(User user, UUID uuid) throws DAOException {
        int res = 0;
        if (connection != null) {
            PreparedStatement preparedStatement = null;
            try {
                preparedStatement = connection.prepareStatement(ADD_SUBSCRIBTION);
                preparedStatement.setObject(1, user.getUuid());
                preparedStatement.setObject(2, uuid);
                res = preparedStatement.executeUpdate();
            } catch (SQLException e) {
                logger.error("Could not add course " + e.getMessage());
                throw new DAOException(e.getMessage());
            } finally {
                if (preparedStatement != null) {
                    close(preparedStatement);
                }
            }
        } else {
            throw new DAOException("No connection available");
        }
        if (res > 0) return true;
        else return false;
    }

    @Override
    public Object execute(DAOManager daoManager) {
        return null;
    }

    public Boolean removeCourse(User user, UUID uuid) throws DAOException {
        int res = 0;
        if (connection != null) {
            PreparedStatement preparedStatement = null;
            try {
                preparedStatement = connection.prepareStatement(REMOVE_SUBSCRIBTION);
                preparedStatement.setObject(1, user.getUuid());
                preparedStatement.setObject(2, uuid);
                res = preparedStatement.executeUpdate();
            } catch (SQLException e) {
                logger.error("Could not remove course " + e.getMessage());
                throw new DAOException(e.getMessage());
            } finally {
                if (preparedStatement != null) {
                    close(preparedStatement);
                }
            }
        }  else {
            throw new DAOException("No connection available");
        }
        if (res > 0) return true;
        else return false;
    }

    public void close(PreparedStatement statement) {
        try {
            statement.close();
        } catch (SQLException e) {
            logger.error(e.getMessage());
        }
    }
}
